#include "dbusargvitem.hpp"
#include <QtDBus>

#define DBUS_BASE_TYPE_COUNT 14
static QString g_basetyes ="ybnqiuxtdsoghv";
static int g_ctypes[DBUS_BASE_TYPE_COUNT] ={QMetaType::UChar
                      ,QMetaType::Bool
                      ,QMetaType::Short
                      ,QMetaType::UShort
                      ,QMetaType::Int
                      ,QMetaType::UInt
                      ,QMetaType::LongLong
                      ,QMetaType::ULongLong
                      ,QMetaType::Double
                      ,QMetaType::QString
                      ,qMetaTypeId<QDBusObjectPath>()
                      ,qMetaTypeId<QDBusSignature>()
                      ,qMetaTypeId<QDBusUnixFileDescriptor>()
                      ,qMetaTypeId<QDBusVariant>()
                     };
static QString g_ctypes_name[DBUS_BASE_TYPE_COUNT] ={"UINT8"
                      ,"Bool"
                      ,"INT16"
                      ,"UINT16"
                      ,"INT32"
                      ,"UINT32"
                      ,"INT64"
                      ,"UINT64"
                      ,"Double"
                      ,"String"
                      ,"QDBusObjectPath"
                      ,"QDBusSignature"
                      ,"QDBusUnixFileDescriptor"
                      ,"QDBusVariant"
                     };
DBusArgvItem::DBusArgvItem(const QStringList &name, const QStringList &DBusArgs)
{
    parentItem = Q_NULLPTR;
    m_level = LEVEL_ROOT;
    for(int i=0;i<DBusArgs.count ();i++)
    {
        DBusArgvItem *item = new DBusArgvItem(name.at (i),DBusArgs.at (i),this);
        item->buildItem ();
        childItems.append (item);
    }
}

DBusArgvItem::DBusArgvItem(const QStringList &name, const QList<int> &DBusArgs)
{
    parentItem = Q_NULLPTR;
    m_level = LEVEL_ROOT;
    for(int i=0;i<DBusArgs.count ();i++)
    {
        DBusArgvItem *item = new DBusArgvItem(name.at (i),DBusArgs.at (i),this);
        item->buildItem ();
        childItems.append (item);
    }
}
DBusArgvItem::DBusArgvItem(const QStringList &name,const QList<DVariant> values)
{
    parentItem = Q_NULLPTR;
    m_level = LEVEL_ROOT;
    for(int i=0;i<values.count ();i++)
    {
        DBusArgvItem *item = new DBusArgvItem(name.at (i),values.at (i),this);
        item->buildItem (values.at (i));
        childItems.append (item);
    }
}

DBusArgvItem::DBusArgvItem(const QString &name, const int &DBusArgs, DBusArgvItem *parent)
{
    if(parent!=Q_NULLPTR)
    {
        this->setLevel (parent->getLevel ()+1);
    }
    parentItem = parent;
    m_Name = name;
    m_ValueDBusArgs = "";
    m_ValueType = DBusArgs;
    m_TypeName = getTypeNameFromType (m_ValueType);
    m_parenttype = QMetaType::UnknownType;
}
DBusArgvItem::DBusArgvItem(const QString &name, const DVariant &value, DBusArgvItem *parent)
{
    if(parent!=Q_NULLPTR)
    {
        this->setLevel (parent->getLevel ()+1);
    }
    parentItem = parent;
    m_Name = name;
    m_ValueDBusArgs = value.m_argTypes;
    m_ValueType = value.m_type;
    m_TypeName = getTypeNameFromType (m_ValueType);
    m_parenttype = QMetaType::UnknownType;
}

DBusArgvItem::DBusArgvItem(const QString &name,const QString &DBusArgs,DBusArgvItem *parent)
{
    if(parent!=Q_NULLPTR)
    {
        this->setLevel (parent->getLevel ()+1);
    }
    parentItem = parent;
    m_Name = name;



    m_ValueDBusArgs = DBusArgs;
//    m_KeysDBusArgs = "";

    m_ValueType = getItemType(m_ValueDBusArgs);
//    m_keyType = QMetaType::UnknownType;

    m_TypeName = getTypeNameFromType (m_ValueType);
    m_parenttype = QMetaType::UnknownType;
}

DBusArgvItem::DBusArgvItem(const QString &name, const QString &DBusArgs, DBusArgvItem *parent, int parenttype)
{
    if(parent!=Q_NULLPTR)
    {
        this->setLevel (parent->getLevel ()+1);
    }
    parentItem = parent;
    m_Name = name;

    m_ValueDBusArgs = DBusArgs;

    m_ValueType = getItemType(m_ValueDBusArgs);

    m_TypeName = getTypeNameFromType (m_ValueType);
    m_parenttype = parenttype;
    print();
}
DBusArgvItem::DBusArgvItem(const QString &name, const DVariant &value, DBusArgvItem *parent, int parenttype)
{
    if(parent!=Q_NULLPTR)
    {
        this->setLevel (parent->getLevel ()+1);
    }
    parentItem = parent;
    m_Name = name;

    m_ValueDBusArgs = value.getArgTypes ();

    m_ValueType = getItemType(m_ValueDBusArgs);

    m_TypeName = getTypeNameFromType (m_ValueType);
    m_parenttype = parenttype;
    print();
}
DVariant DBusArgvItem::getArg(bool *ok)
{
     DVariant d;
     *ok = true;
     d.m_argTypes = m_ValueDBusArgs;
//     d.m_Subtypes = m_subTypes;
     d.m_type = m_ValueType;
     d.m_showModel = m_showModel;
    if(this->getValueType () == DBUS_TYPE_STRUCT)
    {
        structs use;
        use.m_argTypes = m_ValueDBusArgs;
        foreach (auto var, childItems) {
            bool ok1=false;
            use.Values.append (var->getArg (&ok1));
            if(!ok1)
            {
                *ok = ok1;
            }
            use.m_Subtypes<<var->m_ValueType;
        }
        d.setValue (use);
    }else if(this->getValueType () == DBUS_TYPE_ARRAR)
    {
        array use;
        use.m_argTypes = m_ValueDBusArgs;
        use.m_Subtypes<<childItems.first ()->m_ValueType;
        foreach (auto var, childItems) {
            if(var->m_value.isValid ())
            {
                bool ok1=false;
                DVariant d = var->getArg (&ok1);
                if(!ok1)
                {
                    *ok = ok1;
                }
                use.Values.append (d);
            }
        }
        d.setValue (use);
    }else if(this->getValueType () == DBUS_TYPE_DICT)
    {
        dict use;
        use.m_argTypes = m_ValueDBusArgs;
        use.m_Subtypes<<childItems.at (0)->m_ValueType;
        use.m_Subtypes<<childItems.at (1)->m_ValueType;
        for(int i=0;i<childItems.count ();i += 2)
        {
            bool ok1=false;
            bool ok2=false;
            DBusArgvItem *var0 = childItems.at (i);
            DBusArgvItem *var1 = childItems.at (i+1);
            if(var0->m_value.isValid () && var1->m_value.isValid ())
            {
                use.keys.append(var0->getArg (&ok1));
                use.Values.append (var1->getArg (&ok2));
                if(!ok1)
                {
                    *ok = ok1;
                }
                if(!ok2)
                {
                    *ok = ok2;
                }
            }
        }
        d.setValue (use);
    }else
    {
        if(!m_value.convert (m_ValueType))
        {
            *ok = false;
        }
        if(m_ValueType==QMetaType::QString)
        {
            QString str = m_value.toString ();
            str.replace ("\\r","\r");
            str.replace ("\\n","\n");
            d.setValue (str,QMetaType::QString);
        }else if(m_ValueType==QMetaType::QByteArray)
        {
            QByteArray str = m_value.toByteArray ();
            str.replace ("\\r","\r");
            str.replace ("\\n","\n");
            d.setValue (str,QMetaType::QByteArray);
        }else
        {
            d.setValue (m_value,m_ValueType);
        }
    }
    return d;
}
QList<DVariant> DBusArgvItem::getArgs(bool *ok)
{
    QList<DVariant> rets;
    if(m_level == LEVEL_ROOT)
    {
        *ok = true;
        foreach (auto var, this->childItems) {
            bool ok1 = false;
            rets<<var->getArg (&ok1);
            if(!ok1)
            {
                *ok =false;
            }
        }
    }
    return rets;
}
void DBusArgvItem::print()
{
//    qDebug()<<m_Name<<m_ValueDBusArgs<<m_KeysDBusArgs<<m_ValueType<<m_keyType<<m_TypeName<<m_parenttype<<parentItem;
}
QString DBusArgvItem::getTypeNameFromType(int type)
{
    if(type == DBUS_TYPE_STRUCT)
    {
        return "Struct";
    }else if(type == DBUS_TYPE_DICT)
    {
        return "Dict";
    }else if(type == DBUS_TYPE_ARRAR)
    {
        return "Array";
    }else
    {
        return QMetaType::typeName (type);
    }
}
bool DBusArgvItem::buildItem()
{

    if(m_ValueType<QMetaType::User)
    {
        if(m_ValueType == QMetaType::Char
                     || m_ValueType == QMetaType::UChar
                     || m_ValueType == QMetaType::Short
                     || m_ValueType == QMetaType::UShort
                     || m_ValueType == QMetaType::Int
                     || m_ValueType == QMetaType::UInt
                     || m_ValueType == QMetaType::LongLong
                     || m_ValueType == QMetaType::ULongLong
                     )
            {
                m_value = 0;
            }else if(m_ValueType == QMetaType::Bool)
            {
                m_value = false;
            }else if(m_ValueType == QMetaType::QString
                     || m_ValueType == QMetaType::QByteArray
                     )
            {
                m_value = "";
            }

        return true;
    }else if(m_ValueType == DBUS_TYPE_DICT)
    {
        QString key_type;
        QString value_type;
        QString out = m_ValueDBusArgs.mid (2);
        if(getNextType(out,key_type,out)<0)
            return false;
        if(getNextType(out,value_type,out)<0)
            return false;
        QString ch_name = QString::number (childItems.count ());
        m_subTypes<<key_type<<value_type;
        DBusArgvItem *itemk = new DBusArgvItem(ch_name,m_subTypes.at (0),this,DBUS_TYPE_DICT);
        itemk->buildItem();
        childItems.append (itemk);
        DBusArgvItem *itemv = new DBusArgvItem(ch_name,m_subTypes.at (1),this,DBUS_TYPE_DICT);
        itemv->buildItem();
        childItems.append (itemv);
        return true;
    }else if(m_ValueType == DBUS_TYPE_ARRAR)
    {
        QString value_type;
        QString out = m_ValueDBusArgs.mid (1);
        if(getNextType(out,value_type,out)<0)
            return false;
        QString ch_name = QString::number (childItems.count ());

        DBusArgvItem *item = new DBusArgvItem(ch_name,value_type,this,DBUS_TYPE_ARRAR);
        item->buildItem();
        m_subTypes<<item->getValueDBusArgs ();
        childItems.append (item);
        return true;
    }else if(m_ValueType == DBUS_TYPE_STRUCT)
    {
        QString value_type;
        QString out = m_ValueDBusArgs.mid (1);
        while (!out.isEmpty ()) {
            value_type = "";
            int ntype = getNextType(out,value_type,out);
            if(ntype<0)
                return false;
            QString ch_name = QString::number (childItems.count ());
            DBusArgvItem *item = new DBusArgvItem(ch_name,value_type,this,DBUS_TYPE_STRUCT);
            item->buildItem();
            childItems.append (item);
            m_subTypes<<item->getValueDBusArgs ();
            if(out.startsWith (")"))
                return true;
        }
    }else
    {
        return false;
    }
}

bool DBusArgvItem::buildItem(const DVariant value)
{
    m_ValueType = value.type ();
    m_ValueDBusArgs = value.getArgTypes ();
    m_showModel = value.m_showModel;

    if(m_ValueType == DBUS_TYPE_DICT)
    {
        bool ok =false;
        dict d = value.getDict (&ok);
        if(!ok)
        {
            return false;
        }
        m_ValueDBusArgs = d.m_argTypes;

        QString key_type;
        QString value_type;
        QString out = m_ValueDBusArgs.mid (2);
        if(getNextType(out,key_type,out)<0)
            return false;
        if(getNextType(out,value_type,out)<0)
            return false;
        QString ch_name = QString::number (childItems.count ());
        m_subTypes<<key_type<<value_type;
        for(int i=0;i<d.keys.count () && i<d.Values.count ();i++)
        {
            DBusArgvItem *itemk = new DBusArgvItem(ch_name,d.keys.at (i),this,DBUS_TYPE_DICT);
            itemk->buildItem(d.keys.at (i));
            childItems.append (itemk);
            DBusArgvItem *itemv = new DBusArgvItem(ch_name,d.Values.at (i),this,DBUS_TYPE_DICT);
            itemv->buildItem(d.Values.at (i));
            childItems.append (itemv);
        }
        DBusArgvItem *itemk = new DBusArgvItem(ch_name,m_subTypes.at (0),this,DBUS_TYPE_DICT);
        itemk->buildItem();
        childItems.append (itemk);
        DBusArgvItem *itemv = new DBusArgvItem(ch_name,m_subTypes.at (1),this,DBUS_TYPE_DICT);
        itemv->buildItem();
        childItems.append (itemv);
        return true;
    }else if(m_ValueType == DBUS_TYPE_ARRAR)
    {
        bool ok =false;
        array d = value.getArray (&ok);
        if(!ok)
        {
            return false;
        }
        QString value_type;
        QString out = m_ValueDBusArgs.mid (1);
        if(getNextType(out,value_type,out)<0)
            return false;
        QString ch_name = QString::number (childItems.count ());
        foreach (auto var, d.Values) {
            DBusArgvItem *item = new DBusArgvItem(ch_name,var,this,DBUS_TYPE_ARRAR);
            item->buildItem(var);
            childItems.append (item);
        }
        DBusArgvItem *item = new DBusArgvItem(ch_name,value_type,this,DBUS_TYPE_ARRAR);
        item->buildItem();
        m_subTypes<<item->getValueDBusArgs ();
        childItems.append (item);
        return true;
    }else if(m_ValueType == DBUS_TYPE_STRUCT)
    {
        bool ok =false;
        structs d = value.getStruct (&ok);
        if(!ok)
        {
            return false;
        }
        QString value_type;
        QString out = m_ValueDBusArgs.mid (1);
        QString ch_name = QString::number (childItems.count ());
        foreach (auto var, d.Values) {
            DBusArgvItem *item = new DBusArgvItem(ch_name,var,this,DBUS_TYPE_STRUCT);
            item->buildItem(var);
            childItems.append (item);
        }
    }else
    {
        m_value = value.m_Values;
        return true;
    }
}

bool DBusArgvItem::insertSubItem()
{
    QString ch_name = QString::number (childItems.count ());
    if(getValueType()== DBUS_TYPE_ARRAR)
    {

        DBusArgvItem *item = new DBusArgvItem(ch_name,m_subTypes.at (0),this,DBUS_TYPE_ARRAR);
        item->buildItem();
        childItems.append (item);
        return true;
    }else if(getValueType () == DBUS_TYPE_DICT)
    {
        DBusArgvItem *itemk = new DBusArgvItem(ch_name,m_subTypes.at (0),this,DBUS_TYPE_DICT);
        itemk->buildItem();
        childItems.append (itemk);
        DBusArgvItem *itemv = new DBusArgvItem(ch_name,m_subTypes.at (1),this,DBUS_TYPE_DICT);
        itemv->buildItem();
        childItems.append (itemv);
        return true;
    }else
    {
    }
    return false;
}

int DBusArgvItem::addChild(DBusArgvItem *item)
{
    childItems.append (item);
    return childItems.count ()-1;
}

QString DBusArgvItem::getArraySubArgType()
{
    if(m_ValueType == DBUS_TYPE_ARRAR)
    {
        QString out = m_ValueDBusArgs.mid (1);
        QString value_type;
        if(getNextType(out,value_type,out)>=0)
        {
            return value_type;
        }

    }
    return "";
}

QString DBusArgvItem::getDictKeyArgType()
{
    if(m_ValueType == DBUS_TYPE_DICT)
    {
        QString out = m_ValueDBusArgs.mid (2);
        QString value_type;
        if(getNextType(out,value_type,out)>=0)
        {
            return value_type;
        }
    }
    return "";
}

QString DBusArgvItem::getDictValueArgType()
{
    if(m_ValueType == DBUS_TYPE_DICT)
    {
        QString out = m_ValueDBusArgs.mid (2);
        QString value_type;
        if(getNextType(out,value_type,out)>=0)
        {
            if(getNextType(out,value_type,out)>=0)
            {
                return value_type;
            }
        }

    }
    return "";
}

int DBusArgvItem::adjustItem(int &addRowfrom,int &addRowto)
{
    addRowfrom = addRowto = 0;
    if(m_parenttype == DBUS_TYPE_ARRAR)
    {
        if(parentItem->getChildItems ().last () == this)
        {

            DBusArgvItem *item = new DBusArgvItem("",m_ValueDBusArgs,parentItem,DBUS_TYPE_ARRAR);
            item->buildItem ();
            addRowfrom = addRowto = parentItem->addChild(item);
            return addRowfrom;
        }
    }else if(m_parenttype == DBUS_TYPE_DICT)
    {
        if(parentItem->getChildItems ().last () == this)
        {
            DBusArgvItem *itemkey = parentItem->getChildItems ().first ();

            DBusArgvItem *itemk = new DBusArgvItem("",itemkey->getValueDBusArgs (),parentItem,DBUS_TYPE_DICT);
            itemk->buildItem();
            addRowfrom = parentItem->addChild (itemk);
            DBusArgvItem *itemv = new DBusArgvItem("",m_ValueDBusArgs,parentItem,DBUS_TYPE_DICT);
            itemv->buildItem();
            addRowto = parentItem->addChild (itemv);
            return addRowfrom;
        }
    }
    return -1;
}

QVariant DBusArgvItem::getName() const
{
    int c = childNumber();
    if (m_level == LEVEL_TOP)
    {
        return m_Name;
    }else if(getParenttype() == DBUS_TYPE_DICT){
        if(c%2==0)
        {
            return "key";
        }else
        {
            return "Value";
        }
    }
    else
    {
        return QString::number (c);
    }
}



int DBusArgvItem::getItemType(const QString &DBusArgs)
{
    if(DBusArgs.startsWith ("ay"))
    {
        return qMetaTypeId<QByteArray>();
    }else if(DBusArgs.startsWith ("a{"))
    {
        return DBUS_TYPE_DICT;
    }else if(DBusArgs.startsWith ("a"))
    {
        return DBUS_TYPE_ARRAR;
    }else if(DBusArgs.startsWith ("("))
    {
        return DBUS_TYPE_STRUCT;
    }else
    {
        const QChar c = DBusArgs.at (0);
        int index = g_basetyes.indexOf (c);
        if(index>=0 && index<DBUS_BASE_TYPE_COUNT)
        {
            return g_ctypes[index];
        }
        return QMetaType::UnknownType;
    }
}

bool DBusArgvItem::getDictType(QString DBusArgs,QString &key,QString &Value,QString &out)
{
    QString strRet;
    QString basetyes ="ybnqiuxtdoghv";
    QChar var = DBusArgs.at (0);
    if(basetyes.contains (var))
    {
        key = DBusArgs.left (1);
        out = DBusArgs.mid (1);
    }else if(DBusArgs.startsWith ("ay"))
    {
        key = DBusArgs.left (2);
        out = DBusArgs.mid (2);
    }else
    {
        return false;
    }
    var = out.at (0);
    if(basetyes.contains (var))
    {
        Value = out.left (1);
        out = out.mid (1);
        if(out.startsWith ("}"))
        {
            return true;
        }
    }else if(out.startsWith ("ay}"))
    {
        Value = out.left (2);
        out = out.mid (3);
        return true;
    }
    return false;
}

QList<DBusArgvItem *> DBusArgvItem::getChildItems() const
{
    return childItems;
}

int DBusArgvItem::getLevel() const
{
    return m_level;
}

void DBusArgvItem::setLevel(int level)
{
    m_level = level;
}

DBusArgvItem *DBusArgvItem::getParentItem() const
{
    return parentItem;
}

QString DBusArgvItem::getValueDBusArgs() const
{
    return m_ValueDBusArgs;
}

//QString DBusArgvItem::getKeysDBusArgs() const
//{
//    return m_KeysDBusArgs;
//}

int DBusArgvItem::getValueType() const
{
    return m_ValueType;
}

//int DBusArgvItem::getKeyType() const
//{
//    return m_keyType;
//}

QString DBusArgvItem::getTypeName() const
{
    return m_TypeName;
}

int DBusArgvItem::getParenttype() const
{
    return m_parenttype;
}

QVariant DBusArgvItem::getValue() const
{
    return m_value;
}

//QVariant DBusArgvItem::getKey() const
//{
//    return m_key;
//}

int DBusArgvItem::getNextType(QString DBusArgs,QString &Value,QString &out)
{
    QString basetyes ="ybnqiuxtdsoghv";
    if(DBusArgs.isEmpty ())
    {
        return Flag_ERROR_EMPTY;
    }
    QChar var = DBusArgs.at (0);
    if(basetyes.contains (var))
    {
        Value = DBusArgs.left (1);
        out = DBusArgs.mid (1);
        return Flag_BASE_SUCCESS;
    }else if(DBusArgs.startsWith ("ay"))
    {
        Value = DBusArgs.left (2);
        out = DBusArgs.mid (2);
        return Flag_BASE_SUCCESS;
    }else if(DBusArgs.startsWith ("a{"))
    {
        Value.append ("a{");
        QString keys="";
        QString Values="";
        out = DBusArgs.mid (2);
        if(!getNextType(out,keys,out))
        {
            return Flag_ERROR_DICT_KEY;
        }
        if(!getNextType(out,Values,out))
        {
            return Flag_ERROR_DICT_VALUE;
        }

        Value.append (keys);
        Value.append (Values);
        Value.append ("}");
        if(out.startsWith ("}"))
        {
            out= out.mid (1);
            return Flag_DICT_SUCCESS;
        }
    }else if(DBusArgs.startsWith ("a"))
    {
        Value.append ("a");
        QString Values="";
        out = DBusArgs.mid (1);
        if(getNextType(out,Values,out))
        {
            Value.append (Values);
        }else
        {
            return Flag_ERROR_ARRAY_VALUE;
        }
        return Flag_ARRAY_SUCCESS;
    }else if(DBusArgs.startsWith ("("))
    {
        Value.append ("(");
        QString keys="";
        QString Values="";
        out = DBusArgs.mid (1);
        while (!out.startsWith (")")) {
            if(getNextType(out,Values,out))
            {
                Value.append (Values);
                if(out.length ()==0)
                {
                    return Flag_ERROR_STRUCT;
                }
            }else
            {
                return Flag_ERROR_STRUCT;
            }
        }
        Value.append (")");
        out = out.mid (1);
        return Flag_STRUCT_SUCCESS;
    }
    return false;
}



//void DBusArgvItem::buildStruct()
//{

//    while (true) {

//    }
//}

bool DBusArgvItem::getTypes(QString DBusArgs, int &ctype, QString &typeName, QValidator **validator)
{
    if(DBusArgs.startsWith ("a{"))
    {
        typeName = "dict";
        ctype = qMetaTypeId<dict>();

    }else if(DBusArgs.startsWith ("("))
    {
        typeName = "struct";
        ctype = qMetaTypeId<structs>();

    }else if(DBusArgs.startsWith ("ay"))
    {
        typeName = "Bytes";
        ctype = qMetaTypeId<QByteArray>();
    }else if(DBusArgs.startsWith ("a"))
    {
        typeName = "array";
        ctype = qMetaTypeId<array>();
//        buildList();
    }else if(DBusArgs.startsWith ("y"))
    {
        ctype = QMetaType::Char;
        typeName = "Byte";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setRange(0,255);

    }else if(DBusArgs.startsWith ("b"))
    {
        ctype = QMetaType::Bool;
        typeName = "Bool";
    }else if(DBusArgs.startsWith ("n"))
    {
        ctype = QMetaType::Short;
        typeName = "Int16";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setRange(-32768,32767);

    }else if(DBusArgs.startsWith ("q"))
    {
        ctype = QMetaType::UShort;
        typeName = "UInt16";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setRange(0,65535);

    }else if(DBusArgs.startsWith ("i"))
    {
        ctype = QMetaType::Int;
        typeName = "Int32";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setRange(-2147483648,2147483648);

    }else if(DBusArgs.startsWith ("u"))
    {
        ctype = QMetaType::UInt;
        typeName = "UInt32";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setRange(0,4294967295);

    }else if(DBusArgs.startsWith ("x"))
    {
        ctype = QMetaType::LongLong;
        typeName = "Int64";
        *validator = new QIntValidator(this);

    }else if(DBusArgs.startsWith ("t"))
    {
        ctype = QMetaType::ULongLong;
        typeName = "UInt64";
        *validator = new QIntValidator(this);
        ((QIntValidator*)*validator)->setBottom(0);
    }else if(DBusArgs.startsWith ("d"))
    {
        ctype = QMetaType::Double;
        typeName = "double";
        *validator = new QDoubleValidator(this);
    }else if(DBusArgs.startsWith ("s"))
    {
        ctype = QMetaType::QString;
        typeName = "string";
    }else if(DBusArgs.startsWith ("o"))
    {
        ctype = qMetaTypeId<QDBusObjectPath>();
        typeName = "DBusPath";
    }else if(DBusArgs.startsWith ("g"))
    {
        ctype = qMetaTypeId<QDBusSignature>();
        typeName = "DBusSignal";
    }else if(DBusArgs.startsWith ("h"))
    {
        ctype = qMetaTypeId<QDBusUnixFileDescriptor>();
        typeName = "UNIX_FD";
    }else if(DBusArgs.startsWith ("v"))
    {
        ctype = qMetaTypeId<QDBusVariant>();
        typeName = "Variant";
    }else
    {
        ctype = QMetaType::UnknownType;
        typeName = "UnknownType";
    }
    return true;
}

DBusArgvItem::~DBusArgvItem()
{
    qDeleteAll(childItems);
}
DBusArgvItem *DBusArgvItem::child(int number)
{
    return childItems.value(number);
}
int DBusArgvItem::childCount() const
{
    return childItems.count();
}

int DBusArgvItem::childNumber() const
{
    if (parentItem)
        return parentItem->childItems.indexOf(const_cast<DBusArgvItem*>(this));

    return -1;
}

int DBusArgvItem::columnCount() const
{
    return 4;
}
QVariant DBusArgvItem::data(int column)
{

    if(parentItem == Q_NULLPTR)
    {
        return QVariant();
    }
    if(column == 0)
    {
        if(parentItem->m_ValueType == DBUS_TYPE_STRUCT||
                parentItem->m_ValueType == DBUS_TYPE_ARRAR)
        {
            int index = parentItem->childItems.indexOf (this);
            return index+1;
        }else if(parentItem->m_ValueType == DBUS_TYPE_DICT)
        {
            int index = parentItem->childItems.indexOf (this)/2;
            return QString::number (index+1);
        }else if(parentItem->m_ValueType == QMetaType::UnknownType)
        {
            return m_Name;
        }else
        {
            return m_Name;
        }
    }else if(column == 1)
    {
        return m_TypeName;
    }else if(column == 2)
    {
        if(m_ValueType == DBUS_TYPE_STRUCT){
            QString ret = "(";
            if(childItems.count ()>0)
            {
                ret.append (childItems.first ()->data (2).toString ());
            }
            for (int i=1;i<childItems.count ();i++) {
                ret.append (",");
                ret.append (childItems.at (i)->data (2).toString ());
            }
            ret +=")";
            return ret;
        }
        else if(m_ValueType == DBUS_TYPE_ARRAR)
        {
            QString ret = "[";
            if(childItems.count ()>0)
            {
                ret.append (childItems.first ()->data (2).toString ());
            }
            for (int i=1;i<childItems.count ();i++) {
                ret.append (",");
                ret.append (childItems.at (i)->data (2).toString ());
            }
            ret +="]";
            return ret;
        }else if(m_ValueType == DBUS_TYPE_DICT)
        {
            QString ret = "{";
            if(childItems.count ()>0)
            {
                ret.append (childItems.first ()->data (2).toString ());
            }
            for (int i=1;i<childItems.count ();i++) {
                ret.append (",");
                ret.append (childItems.at (i)->data (2).toString ());
            }
            ret +="}";
            return ret;
        }else if(m_ValueType == QMetaType::UnknownType)
        {
            return QVariant();
        }else
        {
            if(m_ValueType == QMetaType::Char
                    || m_ValueType == QMetaType::Short
                    || m_ValueType == QMetaType::Int
                    || m_ValueType == QMetaType::LongLong
                    )
            {
                int size = QMetaType::sizeOf(m_ValueType);
                m_value.convert (m_ValueType);
                if(m_showModel == ShowModelHex)
                {
                    return QString::number (m_value.toLongLong (),16).right (size*2);;
                }else
                {
                    return m_value.toLongLong ();
                }
            }else if(m_ValueType == QMetaType::UChar
                    || m_ValueType == QMetaType::UShort
                    || m_ValueType == QMetaType::UInt
                    || m_ValueType == QMetaType::ULongLong
                    )
            {
                int size = QMetaType::sizeOf(m_ValueType);
                m_value.convert (m_ValueType);
                if(m_showModel == ShowModelHex)
                {
                    return QString::number (m_value.toULongLong (),16).right(size*2);;
                }else
                {
                    return m_value.toULongLong ();
                }
            }else if(m_ValueType == QMetaType::QByteArray)
            {
                if(m_showModel == ShowModelHex)
                {
                    return QString(m_value.toByteArray ().toHex (' '));
                }else
                {
                    QByteArray arr =  m_value.toByteArray ();
                    arr.replace ("\r","\\r");
                    arr.replace ("\n","\\n");
                    return arr;
                }
            }else if(m_ValueType == QMetaType::QString)
            {
                QString arr =  m_value.toString ();
                arr.replace ("\r","\\r");
                arr.replace ("\n","\\n");
                return arr;
            }
            return m_value;
        }

    }
    return QVariant();
}

//bool DBusArgvItem::insertChildren(int position, int count, int columns)
//{
//    if (position < 0 || position > childItems.size())
//        return false;

//    for (int row = 0; row < count; ++row) {
//        QVector<QVariant> data(columns);
//        DBusArgvItem *item = new DBusArgvItem(data, this);
//        childItems.insert(position, item);
//    }

//    return true;
//}
//bool DBusArgvItem::insertColumns(int position, int columns)
//{
//    if (position < 0 || position > itemData.size())
//        return false;

//    for (int column = 0; column < columns; ++column)
//        itemData.insert(position, QVariant());

//    foreach (DBusArgvItem *child, childItems)
//        child->insertColumns(position, columns);

//    return true;
//}
DBusArgvItem *DBusArgvItem::parent()
{
    return parentItem;
}
//bool DBusArgvItem::removeChildren(int position, int count)
//{
//    if (position < 0 || position + count > childItems.size())
//        return false;

//    for (int row = 0; row < count; ++row)
//        delete childItems.takeAt(position);

//    return true;
//}

bool DBusArgvItem::setValue(const QVariant &value)
{
    m_value = value;
    return true;
}

